package cn.cctvcc.email.service;

import cn.cctvcc.core.domain.R;
import cn.cctvcc.core.enums.system.SysEmailTypeEnum;
import cn.cctvcc.system.api.RemoteSysEmailService;
import cn.cctvcc.system.api.domain.SysEmail;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.File;
import java.util.Objects;

/**
 * @description: 发送邮件
 * @author: Jiang
 * @create: 2021-09-28 10:50
 */
@Component
public class EmailService {

    private static final Logger log = LoggerFactory.getLogger(EmailService.class);

    @Value("${spring.mail.username}")
    private String from;

    @Autowired
    private JavaMailSender javaMailSender;
    @Autowired
    private RemoteSysEmailService remoteSysEmailService;


    /**
     * 发送邮件接口
     */
    public R sendMail(SysEmail sysEmail) {

        try{
            if(Objects.equals(SysEmailTypeEnum.普通邮件.getCode(), sysEmail.getEmailType()))
                this.sendSimpleMail(sysEmail);
            if(Objects.equals(SysEmailTypeEnum.HTML邮件.getCode(), sysEmail.getEmailType()))
                this.sendHtmlEmail(sysEmail);
            if(Objects.equals(SysEmailTypeEnum.带图片的HTML邮件.getCode(), sysEmail.getEmailType()))
                this.sendImgHtmlEmail(sysEmail);
            if(Objects.equals(SysEmailTypeEnum.带附件的邮件.getCode(), sysEmail.getEmailType()))
                this.sendFileEmail(sysEmail);
            return R.ok();
        } catch (Exception e){
            sysEmail.setSendError(e.getMessage());
            remoteSysEmailService.add(sysEmail);// 记录邮件信息
            return R.fail("邮件发送失败，请稍候尝试," + e.getMessage());
        }
    }

    /**
     * 发送普通邮件
     */
    private void sendSimpleMail(SysEmail sysEmail) {

        String[]  emails = sysEmail.getToEmail().split(",");
        for (int i = 0; i < emails.length; i++) {
            String email = emails[i];
            SimpleMailMessage message = new SimpleMailMessage();
            message.setFrom(from);
            message.setTo(email);
//            message.setCc(from); // 抄送人
            message.setSubject(sysEmail.getSubject());
            message.setText(sysEmail.getContent());
            javaMailSender.send(message);
            log.info("普通邮件已经发送, 发送人：" + email + " 内容：" + sysEmail.getContent());
        }
    }

    /**
     * 发送HTML邮件
     */
    private void sendHtmlEmail(SysEmail sysEmail) {
        try {
            //创建一个MINE消息
            MimeMessage message = javaMailSender.createMimeMessage();
            MimeMessageHelper minehelper = new MimeMessageHelper(message, true);
            //谁发
            minehelper.setFrom(from);
            //谁要接收
            minehelper.setTo(sysEmail.getToEmail());
            //邮件主题
            minehelper.setSubject(sysEmail.getSubject());
            //邮件内容   true 表示带有附件或html
            minehelper.setText(sysEmail.getContent(), true);
            javaMailSender.send(message);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 发送带图片的HTML邮件
     * @param sysEmail
     */
    private void sendImgHtmlEmail(SysEmail sysEmail) {

        MultipartFile multipartFile = null;
        String resId = "";
        //创建一个MINE消息
        MimeMessage message = javaMailSender.createMimeMessage();
        try {
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            //谁发
            helper.setFrom(from);
            //谁接收
            helper.setTo(sysEmail.getToEmail());
            //邮件主题
            helper.setSubject(sysEmail.getSubject());
            //邮件内容   true 表示带有附件或html
            //邮件内容拼接
            String content =
                    "<html><body><img width='250px' src='cid:" + resId + "'>" + sysEmail.getContent()
                            + "</body></html>";
            helper.setText(content, true);
            //蒋 multpartfile 转为file
            File multipartFileToFile = MultipartFileToFile(multipartFile);
            FileSystemResource res = new FileSystemResource(multipartFileToFile);

            //添加内联资源，一个id对应一个资源，最终通过id来找到该资源
            helper.addInline(resId, res);
            javaMailSender.send(message);
        } catch (MessagingException e) {
        }
    }

    /**
     * 发送带附件的邮件
     */
    private void sendFileEmail(SysEmail sysEmail) {

        MultipartFile multipartFile = null;
        //创建一个MINE消息
        MimeMessage message = javaMailSender.createMimeMessage();
        try {
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            //谁发
            helper.setFrom(from);
            //谁接收
            helper.setTo(sysEmail.getToEmail());
            //邮件主题
            helper.setSubject(sysEmail.getSubject());
            //邮件内容   true 表示带有附件或html
            helper.setText(sysEmail.getContent(), true);
            File multipartFileToFile = MultipartFileToFile(multipartFile);
            FileSystemResource file = new FileSystemResource(multipartFileToFile);
            String filename = file.getFilename();
            //添加附件
            helper.addAttachment(filename, file);
            javaMailSender.send(message);
        } catch (MessagingException e) {
            e.printStackTrace();
        }
    }

    private File MultipartFileToFile(MultipartFile multiFile) {
        // 获取文件名
        String fileName = multiFile.getOriginalFilename();
        // 获取文件后缀
        String prefix = fileName.substring(fileName.lastIndexOf("."));
        // 若需要防止生成的临时文件重复,可以在文件名后添加随机码

        try {
            File file = File.createTempFile(fileName, prefix);
            multiFile.transferTo(file);
            return file;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}
